package com.link.base.base.common.service;

import com.link.base.user.model.CoreUser;
import com.link.base.base.common.utils.SendSmsUtil;
import com.link.core.util.*;
import com.qcloud.sms.SmsMultiSender;
import com.qcloud.sms.SmsMultiSenderResult;
import com.qcloud.sms.SmsSingleSender;
import com.qcloud.sms.SmsSingleSenderResult;
import com.alibaba.fastjson.JSONObject;

import java.util.*;

import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;

/**
 * @author yipeng.zhu@hand-china.com
 * @version 1.0
 * @date: 13:54 2018/11/29
 */

@Service
public class SendSmsServiceImpl implements SendSmsService {
    private static final Logger logger = LogManager.getLogger(SendSmsServiceImpl.class);
    /**
     * 阿里云短信发送平台主机
     */
    public static final String ALI_HOST = "http://sms.market.alicloudapi.com";
    /**
     * 阿里云平台路径
     */
    public static final String ALI_PATH = "/singleSendSms";
    /**
     * 阿里云短信发送平台用于验证的key
     */
    private static final String ALI_APPCODE = "APPCODE 43eae9246ced4b228d8f4dffe47b99e9";
    /**
     * 产品签名,不能随便改，需要与阿里云的信息对应上
     */
    public static final String ALI_SIGNAME = "Link产品";
    /**
     * 方法
     */
    public static final String METHOD = "GET";
    /**
     * 腾讯云sdkappid
     */
    public static final int TENCENT_APPID = 1400029749;
    /**
     * 腾讯云appky
     */
    public static final String TENCENT_APPKEY = "9a7f73691ec83dd1691a3266d5205d23";

    private String failStr = "{\"success\":false,\"result\":\"";
    private String sucStr = "{\"success\":true,\"result\":\"成功\"}";

    /**
     * 调用发送短信
     *
     * @param templateCode 模板id
     * @param param        模板参数 json字符串
     * @param msgType      短信类型 可为空
     * @param phoneNumber  手机号
     * @return
     * @author yipeng.zhu@hand-china.com
     */
    @Override
    public String sendSms(String templateCode, String param, String msgType, String phoneNumber) {
        //return aliSendSms(templateCode,param,msgType,phoneNumber); //调用阿里短信发送平台 放开 (不要删除)
        return tencentSendSms(templateCode, param, msgType, phoneNumber);
    }

    /**
     * 阿里云短信发送平台
     *
     * @param templateCode 模板id
     * @param param        模板参数 json字符串
     * @param msgType      短信类型 可为空
     * @param phoneNumber  手机号
     * @return
     * @author yipeng.zhu@hand-china.com
     */
    @Override
    public String aliSendSms(String templateCode, String param, String msgType, String phoneNumber) {
        Map<String, String> params = JsonUtil.fromJsonStringToT(param, Map.class);
        String sendResult = send(phoneNumber, templateCode, params);
        String suc = "\"success\":true";
        if (sendResult.contains(suc)) {
            SendSmsUtil.afterSend(phoneNumber);
            if (!StringUtils.isBlank(msgType)) {
                SendSmsUtil.upsertMsgType(phoneNumber, templateCode, params, msgType);
            }
        }
        return sendResult;
    }

    /**
     * 腾讯腾讯云短信发送平台 (单发)
     *
     * @param templateCode 模板id
     * @param param        模板参数 json 字符串 例如{"name":"用户","url":"url_msg","hint":"hint_msg"} 键不固定； 键值对个数要与申请模板的参数个数相同
     * @param msgType      短信类型 可为空
     * @param phoneNumber  手机号
     * @return
     * @author yipeng.zhu@hand-china.com
     */
    @Override
    public String tencentSendSms(String templateCode, String param, String msgType, String phoneNumber) {
        LinkedHashMap params = JsonUtil.fromJsonStringToT(param, LinkedHashMap.class);
        String beforeSendResult = SendSmsUtil.beforeSend(phoneNumber);
        if (beforeSendResult != null) {
            return beforeSendResult;
        }
        try {
            int temId = Integer.parseInt(templateCode);
            ArrayList<String> paramList = new ArrayList<>(params.values());
            SmsSingleSender singleSender = new com.qcloud.sms.SmsSingleSender(
                    Integer.parseInt(PropertyUtil.getCommonProperty("tencentAppId")), PropertyUtil.getCommonProperty("tencentAppKey"));
            SmsSingleSenderResult singleSenderResult = singleSender.sendWithParam("", phoneNumber, temId, paramList, "", "", "");
            if (singleSenderResult.result == 0) {
                SendSmsUtil.afterSend(phoneNumber);
                if (!StringUtils.isBlank(msgType)) {
                    SendSmsUtil.upsertMsgType(phoneNumber, templateCode, params, msgType);
                }
                logger.debug("短信[" + templateCode + "]发送[ " + phoneNumber + " ] 成功");
                return sucStr;
            } else {
                logger.error(singleSenderResult);
                return failStr + singleSenderResult.errMsg + "\"}";
            }
        } catch (Exception e) {
            logger.error("短信发送[ " + phoneNumber + " ]错误: " + e.getMessage());
            return failStr + e.getMessage() + "\"}";
        }
    }

    /**
     * 腾讯云群发短信消息
     * @author   yipeng.zhu@hand-china.com
     * @param templateCode 模板id
     * @param param        模板参数 json字符串
     * @param msgType      短信类型
     * @param phones       list集合 手机号
     * @return
      */
    @Override
    public String tencentMultiSendSms(String templateCode, String param, String msgType, List<String> phones) {
        LinkedHashMap params = JsonUtil.fromJsonStringToT(param, LinkedHashMap.class);
        int temId = Integer.parseInt(templateCode);
        for (int i = 0; i < phones.size(); i++) {
            String beforeSendResult = SendSmsUtil.beforeSend(phones.get(i));
            if (beforeSendResult != null) {
                return beforeSendResult;
            }
        }
        try {
            ArrayList<String> paramList = new ArrayList<>(params.values());
            SmsMultiSender smsMultiSender = new SmsMultiSender(
                    Integer.parseInt(PropertyUtil.getCommonProperty("tencentAppId")),
                           PropertyUtil.getCommonProperty("tencentAppKey"));
            ArrayList<String> phoneList = (ArrayList)phones;
            SmsMultiSenderResult smsMultiSenderResult = smsMultiSender.sendWithParam("", phoneList, temId, paramList, "", "", "");
            if (smsMultiSenderResult.result == 0) {
                for (int i = 0; i < phones.size(); i++) {
                    SendSmsUtil.afterSend(phones.get(i));
                }
                if (!StringUtils.isBlank(msgType)) {
                    for (int i = 0; i < phones.size(); i++) {
                        SendSmsUtil.upsertMsgType(phones.get(i), templateCode, params, msgType);
                    }
                }
                logger.debug("短信[" + templateCode + "]发送[ " + String.join(",", phones.toArray(new String[phones.size()])) + " ] 成功");
                return sucStr;
            } else {
                logger.error(smsMultiSenderResult);
                return failStr + smsMultiSenderResult.errMsg + "\"}";
            }
        } catch (Exception e) {
            logger.error("短信发送[ " + String.join(",", phones.toArray(new String[phones.size()])) + " ]错误: " + e.getMessage());
            return failStr + e.getMessage() + "\"}";
        }
    }

    /**
     * <p>阿里平台 发送短信</p>
     * @author yrf
     * @param phoneNumber  手机号
     * @param params       发送短信内容
     * @param templateCode 模板id
     * @return
     * @update yipeng.zhu@hand-china.com
     */
    private String send(String phoneNumber, String templateCode, Map<String, String> params) {
        Map<String, String> headers = new HashMap<>(16);
        CoreUser loginUser = UserUtil.getUser();
        //认证
        headers.put("Authorization", PropertyUtil.getProperty("aliAppCode", loginUser.getLoginCorpId()));
        Map<String, String> querys = new HashMap<>(16);
        querys.put("ParamString", (String) JSONObject.toJSONString(params));
        //手机号
        querys.put("RecNum", phoneNumber);
        //签名,不能随便改，需要与阿里云的信息对应上
        querys.put("SignName", PropertyUtil.getProperty("aliSigName", loginUser.getLoginCorpId()));
        //信息模板,不能随便改，需要与阿里云的信息对应上
        querys.put("TemplateCode", templateCode);
        try {
            HttpResponse response = HttpUtils.doGet(PropertyUtil.getProperty("aliHost", loginUser.getLoginCorpId()),
                    PropertyUtil.getProperty("aliPath", loginUser.getLoginCorpId()), METHOD, headers, querys);
            String resultStr = EntityUtils.toString(response.getEntity());
            logger.debug("短信[" + templateCode + "] 发送 [" + phoneNumber + "]: " + resultStr);
            JSONObject jsonObject = JsonUtil.toJsonObject(resultStr);
            return "{\"success\":" + jsonObject.getString("success") + ",\"result\":\"" + jsonObject.getString("message") + "\"}";
        } catch (Exception e) {
            logger.error("MsgUtil捕获异常: ", e);
            return failStr + e.getMessage() + "\"}";
        }
    }


}
